package drds.server.net;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.channels.SocketChannel;

import drds.server.config.ErrorCode;
import drds.server.net.handler.AuthHandler;
import drds.server.net.packet.BytesHolder;
import drds.server.net.packet.ErrorPacket;
import drds.server.net.packet.OkPacket;
import drds.server.net.packet.Packet;
import drds.server.server.SessionContext;

/**
 * 认证和退出和Ping和Pong等生命周期的管理
 * 
 * @author 曹正辉<330937205@qq.com>
 * 
 */
public abstract class SessionContext$LifeCycle extends SessionContext$ReadWrite {

	public SessionContext$LifeCycle(SocketChannel socketChannel) throws IOException {
		super(socketChannel);
		SessionContext sessionContext = null;
		this.handler = new AuthHandler(sessionContext);
	}

	public void setProcessor(SessionContextGroupShareResources processor) {
		super.setProcessor(processor);
		processor.addSessionContext(this);
	}

	protected String sql;

	public String getSql() {
		return sql;
	}

	public void setSql(String sql) {
		this.sql = sql;
	}

	/**
	 * 握手
	 */
	@Override
	public void init() throws IOException {
	}

	public void ping() {
		write(writeToByteBuffer(OkPacket.OK, allocate()));
	}

	public void heartbeat(byte[] bytes) {
		write(writeToByteBuffer(OkPacket.OK, allocate()));
	}

	public void kill(byte[] bytes) {
		writeErrorMessage(ErrorCode.ER_UNKNOWN_COM_ERROR, "Unknown command");
	}

	@Override
	public void close(String reason) {
		super.close(reason);
	}

	public void writeErrorMessage(int errorNo, String message) {
		writeErrorMessage((byte) 1, errorNo, message);
	}

	public void writeErrorMessage(byte id, int errorNo, String message) {
		ErrorPacket errorPacket = new ErrorPacket();
		errorPacket.packetId = id;
		errorPacket.errorNo = errorNo;
		errorPacket.errorMessage = encodeString(message);
		errorPacket.write(this);
	}

	public void query(String sql) {

		if (sql == null || sql.length() == 0) {
			writeErrorMessage(ErrorCode.ER_NOT_ALLOWED_COMMAND, "Empty SQL");
			return;
		}
		// 记录SQL
		this.setSql(sql);

	}

	public void query(byte[] bytes) {

		// 取得语句

		BytesHolder bytesHolder = new BytesHolder(bytes);
		bytesHolder.position(5);
		String sql = bytesHolder.readString();

		this.query(sql);
	}

	public void statementPrepare(byte[] bytes) {

		// 取得语句
		BytesHolder bytesHolder = new BytesHolder(bytes);
		bytesHolder.position(5);
		String sql = bytesHolder.readString();
		if (sql == null || sql.length() == 0) {
			writeErrorMessage(ErrorCode.ER_NOT_ALLOWED_COMMAND, "Empty SQL");
			return;
		}
		// 记录SQL
		this.setSql(sql);

		// 执行预处理

	}

	@Override
	public void handle(final byte[] bytes) {
		/**
		 * 执行退出命令
		 */
		if (bytes.length > 4 //
				&& bytes[0] == 1 //
				&& bytes[1] == 0 //
				&& bytes[2] == 0 //
				&& bytes[3] == 0 //
				&& bytes[4] == Packet.QUIT) { //
			this.close("quit cmd");
			return;
		}
		handler.handle(bytes);
	}

	private final static byte[] encodeString(String string) {
		if (string == null) {
			return null;
		}
		try {
			return string.getBytes("UTF-8");
		} catch (UnsupportedEncodingException e) {
			return string.getBytes();
		}
	}

}